package com.david.flowable.service.Impl;

import com.david.common.exception.FlowException;
import com.david.common.utils.PageResult;
import com.david.flowable.flowfactory.FlowServiceFactory;
import com.david.flowable.mapper.FlowFormMapper;
import com.david.flowable.pojo.dto.FormFlowDTO;
import com.david.flowable.pojo.vo.FormFlowVO;
import com.david.flowable.pojo.vo.FormVO;
import com.david.flowable.service.FlowFormService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.io.IOUtils;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.support.TransactionTemplate;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service
public class FlowFormServiceImpl extends FlowServiceFactory implements FlowFormService {
    @Autowired
    private FlowFormMapper flowFormMapper;

    @Autowired
    private TransactionTemplate transactionTemplate;

    @Override
    public Integer saveForm(FormVO formVO) {
        if (!formVO.getFormContent().isEmpty() && !formVO.getName().isEmpty()) {
            String username = SecurityContextHolder.getContext().getAuthentication().getName();
            LocalDateTime createTime = LocalDateTime.now();
            formVO.setCreateTime(createTime);
            formVO.setCreateBy(username);
            flowFormMapper.insertForm(formVO);
            return formVO.getId();
        } else {
            throw new RuntimeException("表格数据不完整");
        }
    }

    @Override
    public void insertFormFlow(FormFlowVO formFlowVO) {
        formFlowVO.setStatus("启用");
        formFlowVO.setCreateTime(LocalDateTime.now());
        flowFormMapper.insertFormFlow(formFlowVO);
    }

    @Override
    public PageResult selectFormFlow(FormFlowVO formFlowVO) {
        FormFlowDTO formFlowDTO = FormFlowDTO.builder().appName(formFlowVO.getAppName()).processName(formFlowVO.getProcessName()).status(formFlowVO.getStatus()).id(formFlowVO.getId()).build();
        PageHelper.startPage(formFlowVO.getPage(), formFlowVO.getPageSize());
        List<FormFlowDTO> list = flowFormMapper.selectFormFlow(formFlowDTO);
        PageInfo<FormFlowDTO> pageInfo = new PageInfo<>(list);
        PageResult result = PageResult.builder().total((int) pageInfo.getTotal()).records(pageInfo.getList()).build();
        System.out.println(result);
        return result;
    }

    @Override
    public FormVO getFormById(Integer formId) {
        return flowFormMapper.selectFormById(formId);
    }

    @Override
    public void delFormAdnFlow(Integer id) {
        FormFlowDTO formFlowDTO = FormFlowDTO.builder().id(id).build();
        List<FormFlowDTO> list = flowFormMapper.selectFormFlow(formFlowDTO);
        FormFlowDTO formflowgeted = list.get(0);
        if (Objects.isNull(formflowgeted)) {
            throw new FlowException("流程不存在，无法删除");
        }
        transactionTemplate.execute(transactionStatus -> {
            flowFormMapper.deleteForm(formflowgeted.getFormId());
            flowFormMapper.deleteFormFlow(formflowgeted.getId());
            return null;
        });
    }

    @Override
    public void changeFormFlowstatus(Integer id, String status) {
        FormFlowDTO formFlowDTO = FormFlowDTO.builder().id(id).status(status).build();
        flowFormMapper.updateFormFlowStatus(formFlowDTO);
    }

    @Override
    public Map<String, Object> editProcess(Integer id) {
        List<FormFlowDTO> formFlowDTOS = flowFormMapper.selectFormFlow(FormFlowDTO.builder().id(id).build());
        if (formFlowDTOS.isEmpty()) {
            throw new FlowException("流程不存在");
        } else {
            try {
                Map<String, Object> map = new HashMap<>();
                FormFlowDTO formflowgeted = formFlowDTOS.get(0);
                FormVO formVO = flowFormMapper.selectFormById(formflowgeted.getFormId());
                ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(formflowgeted.getFlowId()).singleResult();
                InputStream xml = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getResourceName());
                String xmlStr = IOUtils.toString(xml, StandardCharsets.UTF_8);
                map.put("process", formflowgeted);
                map.put("customForm", formVO);
                map.put("xml", xmlStr);
                return map;
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }

    @Override
    public void updateFormFlowStatus(FormFlowVO formFlowVO) {
        LocalDateTime updateTime = LocalDateTime.now();
        formFlowVO.setUpdateTime(updateTime);
        formFlowVO.setStatus("启用");
        flowFormMapper.updateFormFlow(formFlowVO);
    }
}
